﻿using System;
using System.Diagnostics;

namespace PageAdmin.Utils
{

    /// <summary>
    /// c#调用外部程序的命令帮助类
    /// </summary>
    public class CmdHelper
    {
        /// <summary>
        /// 执行命令,并获取执行结果
        /// </summary>
        /// <param name="processStartInfo"></param>
        /// <param name="outPut"></param>
        /// <param name="error"></param>
        public static void RunCmd(ProcessStartInfo processStartInfo, out string outPut, out string error)
        {
            Process process = new Process(); //实例一个Process类，启动一个独立进程
            //若要在启动进程时使用exe自带的入口程序，UseShellExecute设置为 true；
            //如果需要返回结果，必须设置为false,才能够重定向输入流、输出流和错误流。
            processStartInfo.UseShellExecute = false;
            processStartInfo.RedirectStandardInput = true;  //重定向标准输入
            processStartInfo.RedirectStandardOutput = true; //重定向标准输出  
            processStartInfo.RedirectStandardError = true;   //重定向错误输出
            outPut = null;
            error = null;
            process.StartInfo = processStartInfo;
            try
            {
                process.Start();    //启动
                outPut = process.StandardOutput.ReadToEnd();
                error = process.StandardError.ReadToEnd();
                process.StandardInput.WriteLine("exit");
                process.WaitForExit();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                process.Close();
                process = null;
            }
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="processStartInfo"></param>
        public static void RunCmd(ProcessStartInfo processStartInfo)
        {
            Process process = new Process(); //实例一个Process类，启动一个独立进程
            //若要在启动进程时使用exe自带的入口程序，UseShellExecute设置为 true；
            //如果需要返回结果，必须设置为false,才能够重定向输入流、输出流和错误流。
            processStartInfo.UseShellExecute = false;
            processStartInfo.RedirectStandardInput = true;  //重定向标准输入
            processStartInfo.RedirectStandardOutput = true; //重定向标准输出  
            processStartInfo.RedirectStandardError = true;   //重定向错误输出
            process.StartInfo = processStartInfo;
            try
            {
                process.Start();  //启动
                process.StandardInput.WriteLine("exit");
                process.WaitForExit();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                process.Close();
                process = null;
            }
        }

        /// <summary>
        /// 调用sqlcmd.exe执行sql脚本文件
        /// </summary>
        /// <param name="serverName">服务器名称格式：ip,端口，如：127.0.0.1,1433</param>
        /// <param name="databaseName">数据库名</param>
        /// <param name="user">数据库用户</param>
        /// <param name="password">数据库密码</param>
        /// <param name="sqlFile">要执行的sql脚本文件</param>
        /// <returns></returns>
        public static void SqlCmd(string serverName, string databaseName, string user, string password, string sqlFile)
        {
            sqlFile = IOHelper.MapPath(sqlFile);
            if (IOHelper.FileIsExists(sqlFile))
            {
                string cmd = string.Format(@" -S {0} -d {1} -i ""{2}""", serverName, databaseName, sqlFile);
                if (user != null && password != null)
                {
                    cmd += string.Format(" -U {0} -P {1}", user, password);
                }
                cmd += " -x";
                //导致 sqlcmd 忽略脚本变量，当脚本中包含多个 INSERT 语句，并且这些语句可能包含格式与常规变量，如$(variable_name)格式的字符串时，这一选项很有用。
                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName = "sqlcmd.exe";  //调用的程序名
                processStartInfo.Arguments = cmd;  //设定程式执行参数 
                string outPut, error;
                RunCmd(processStartInfo, out outPut, out error);
                if(!string.IsNullOrEmpty(error))
                {
                    throw new Exception(error);
                }
            }
            else
            {
                throw new Exception(sqlFile + "路径不存在!");
            }
        }
    }
}
